//
// Created by benxb on 2021/12/7.
//

#ifndef BENXDB_POINT_TYPE_H
#define BENXDB_POINT_TYPE_H

#include <cstdint>
#include <string>

namespace benxdb {

// define basic point types

struct PointXYZ {
    uint64_t id;
    union {
        float data[3];
        struct {
            float x;
            float y;
            float z;
        };
    };
};

struct PointSTXYZ {
    uint64_t id;
    uint64_t timestamp;
    uint32_t sweep;
    union {
        float data[4];
        struct {
            float x;
            float y;
            float z;
            float intensity;
        };
    };
};

struct PointSTXYZC {
    uint64_t id;
    uint64_t timestamp;
    uint32_t sweep;
    uint32_t classification;
    union {
        float data[4];
        struct {
            float x;
            float y;
            float z;
        };
    };

    static int col_count() {
        return 6;
    }

    uint32_t col_size(uint32_t col_index) {
        switch (col_index) {
            case 0: return sizeof(sweep);
            case 1: return sizeof(timestamp);
            case 2: return sizeof(classification);
            case 3: return sizeof(x);
            case 4: return sizeof(y);
            case 5: return sizeof(z);
            default:
                return 0;
        }
    }

    static uint32_t col_index(const std::string& col_name) {
        if (col_name == "sweep") {
            return 0;
        } else if (col_name == "timestamp") {
            return 1;
        } else if (col_name == "classification") {
            return 2;
        } else if (col_name == "x") {
            return 3;
        } else if (col_name == "y") {
            return 4;
        } else if (col_name == "z") {
            return 5;
        }
    }

    char* col_data(uint32_t col_index) {
        switch (col_index) {
            case 0: return reinterpret_cast<char *>(&sweep);
            case 1: return reinterpret_cast<char *>(&timestamp);
            case 2: return reinterpret_cast<char *>(&classification);
            case 3: return reinterpret_cast<char *>(&x);
            case 4: return reinterpret_cast<char *>(&y);
            case 5: return reinterpret_cast<char *>(&z);
            default:
                return nullptr;
        }
    }
};

struct PointXYZI {
    uint64_t id;
    union {
        float data[4];
        struct {
            float x;
            float y;
            float z;
            float intensity;
        };
    };
};

}

#endif //BENXDB_POINT_TYPE_H
